#pragma once
#include "Socket.hpp"
#include "Common.hpp"
using namespace SocketModule;
using func_t = std::function<void(const std::shared_ptr<TCPConnectSocket>&)>;

class Server : public NoCopy
{
public:
    Server(in_port_t port, func_t service)
        : _lis_socket(port)
        , _service(service)
    {}

    void Run()
    {
        while(true)
        {
            auto socket = _lis_socket.Accept();
            int id = fork();
            if(id < 0)
            {
                LOG(LogLevel::FATAL) << "fork: 创建子进程失败! " << strerror(errno);
                throw std::runtime_error("fork failed");
            }
            else if( id == 0)
            {
                _lis_socket.Close();
                // 子进程
                if(fork() > 0) exit(NORMAL);
                // 孙子进程
                _service(socket);
                exit(NORMAL);
            }
            else
            {
                // 父进程
                socket->Close();
            }
        }
    }

    ~Server()
    {
        _lis_socket.Close();
    }
private:
    TCPListenSocket _lis_socket;
    func_t _service;
};